/*
 * << Haru Free PDF Library >> -- hpdf_ext_text.c
 *
 * URL: http://libharu.org
 *
 * Copyright (c) 1999-2006 Takeshi Kanno <takeshi_kanno@est.hi-ho.ne.jp>
 * Copyright (c) 2007-2009 Antony Dovgal <tony@daylessday.org>
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.
 * It is provided "as is" without express or implied warranty.
 *
 */

#include "hpdf_conf.h"
#include "hpdf_utils.h"
#include "hpdf_pages.h"
#include "hpdf.h"
#include "dataproc.h"
#include "../ext/hpdf_ext.h"

// 设置线宽，两位小数点
HPDF_EXPORT(HPDF_STATUS)
hpdf_page_set_line_width(
	HPDF_Page page,
	HPDF_INT32 line_width)
{
	HPDF_STATUS ret = HPDF_Page_CheckState(page, HPDF_GMODE_PAGE_DESCRIPTION |
													 HPDF_GMODE_TEXT_OBJECT);
	HPDF_PageAttr attr;
	char pdf_buf[HPDF_TMP_BUF_SIZ];
	char length = 0;

	HPDF_PTRACE((" HPDF_Page_SetLineWidth\n"));

	if (ret != HPDF_OK)
		return ret;

	attr = (HPDF_PageAttr)page->attr;

	length += i32_to_string(pdf_buf, line_width, 0x32, 0x03);
	length += copy_str(" w\n", &pdf_buf[length], 10);

	if (HPDF_Stream_WriteStr(attr->stream, pdf_buf) != HPDF_OK)
		return HPDF_CheckError(page->error);

	attr->gstate->line_width = (float)line_width / 100;

	return ret;
}

// 线端点节点模式 0平头 1圆头 2平头延申0.5w
HPDF_EXPORT(HPDF_STATUS)
hpdf_page_node_mode(
	HPDF_Page page,
	HPDF_INT8 line_join)
{
	HPDF_STATUS ret;

	switch (line_join)
	{
	case 1:
		ret = HPDF_Page_SetLineJoin(page, HPDF_ROUND_JOIN);
		break;
	case 2:
		ret = HPDF_Page_SetLineJoin(page, HPDF_BEVEL_JOIN);
		break;
	default:
		ret = HPDF_Page_SetLineJoin(page, HPDF_MITER_JOIN);
		break;
	}

	return ret;
}

// 线端点节点模式 0平头 1圆头 2平头延申0.5w
HPDF_EXPORT(HPDF_STATUS)
hpdf_page_endpoint_mode(
	HPDF_Page page,
	HPDF_INT8 mode)
{
	HPDF_STATUS ret;

	switch (mode)
	{
	case 1:
		ret = HPDF_Page_SetLineCap(page, HPDF_ROUND_END);
		break;
	case 2:
		ret = HPDF_Page_SetLineCap(page, HPDF_PROJECTING_SQUARE_END);
		break;
	default:
		ret = HPDF_Page_SetLineCap(page, HPDF_BUTT_END);
		break;
	}

	return ret;
}

// 虚线
HPDF_EXPORT(HPDF_STATUS)
hpdf_page_dash_on(
	HPDF_Page page,
	ii16 on, ii16 off,
	uu8 ip_n)
{
	HPDF_STATUS ret = HPDF_Page_CheckState(page, HPDF_GMODE_PAGE_DESCRIPTION |
													 HPDF_GMODE_TEXT_OBJECT);
	char pdf_buf[HPDF_TMP_BUF_SIZ];
	char length = 0;
	HPDF_PageAttr attr;

	HPDF_PTRACE((" HPDF_Page_SetDash\n"));

	if (ret != HPDF_OK)
		return ret;

	pdf_buf[length++] = '[';
	length += i32_to_string(&pdf_buf[length], on, ip_n, 0x03);

	pdf_buf[length++] = ' ';
	length += i32_to_string(&pdf_buf[length], off, ip_n, 0x03);

	length += copy_str("] 0 d\n", &pdf_buf[length], 10);

	attr = (HPDF_PageAttr)page->attr;

	if ((ret = HPDF_Stream_WriteStr(attr->stream, pdf_buf)) != HPDF_OK)
		return HPDF_CheckError(page->error);

	return ret;
}

HPDF_EXPORT(HPDF_STATUS)
hpdf_page_dash_off(HPDF_Page page)
{
	HPDF_STATUS ret = HPDF_Page_CheckState(page, HPDF_GMODE_PAGE_DESCRIPTION |
													 HPDF_GMODE_TEXT_OBJECT);
	HPDF_PageAttr attr;

	HPDF_PTRACE((" HPDF_Page_SetDash\n"));

	if (ret != HPDF_OK)
		return ret;

	attr = (HPDF_PageAttr)page->attr;

	if ((ret = HPDF_Stream_WriteStr(attr->stream, "[] 0 d\n")) != HPDF_OK)
		return HPDF_CheckError(page->error);

	return ret;
}

// 设置画笔颜色-用于划线
HPDF_EXPORT(HPDF_STATUS)
hpdf_page_set_stroke_rgb(
	HPDF_Page page,
	HPDF_INT8 r,
	HPDF_INT8 g,
	HPDF_INT8 b)
{
	HPDF_STATUS ret = HPDF_Page_CheckState(page, HPDF_GMODE_TEXT_OBJECT |
													 HPDF_GMODE_PAGE_DESCRIPTION);
	char pdf_buf[HPDF_TMP_BUF_SIZ];
	char length = 0;
	HPDF_PageAttr attr;

	HPDF_PTRACE((" HPDF_Page_SetRGBStroke\n"));

	if (ret != HPDF_OK)
		return ret;

	if (r < 0 || r > 100 || g < 0 || g > 100 || b < 0 || b > 100)
		return HPDF_RaiseError(page->error, HPDF_PAGE_OUT_OF_RANGE, 0);

	attr = (HPDF_PageAttr)page->attr;

	length += i32_to_string(&pdf_buf[length], r, 0x42, 0x03);
	pdf_buf[length++] = ' ';

	length += i32_to_string(&pdf_buf[length], g, 0x42, 0x03);
	pdf_buf[length++] = ' ';

	length += i32_to_string(&pdf_buf[length], b, 0x42, 0x03);

	copy_str(" RG\n", &pdf_buf[length], 10);

	if (HPDF_Stream_WriteStr(attr->stream, pdf_buf) != HPDF_OK)
		return HPDF_CheckError(page->error);

	// attr->gstate->rgb_stroke.r = r;
	// attr->gstate->rgb_stroke.g = g;
	// attr->gstate->rgb_stroke.b = b;
	attr->gstate->cs_stroke = HPDF_CS_DEVICE_RGB;

	return ret;
}

// 设置路径当前位置坐标
HPDF_EXPORT(HPDF_STATUS)
hpdf_page_move_to(
	HPDF_Page page,
	HPDF_INT32 x,
	HPDF_INT32 y,
	HPDF_UINT8 ip_n)
{
	HPDF_STATUS ret = HPDF_Page_CheckState(page, HPDF_GMODE_PAGE_DESCRIPTION |
													 HPDF_GMODE_PATH_OBJECT);
	char buf[HPDF_TMP_BUF_SIZ];
	char len;
	HPDF_PageAttr attr;

	HPDF_PTRACE((" HPDF_Page_MoveTo\n"));

	if (ret != HPDF_OK)
		return ret;

	attr = (HPDF_PageAttr)page->attr;

	len = i32_to_string(buf, x, ip_n, 0x03);
	buf[len++] = ' ';
	len += i32_to_string(buf + len, y, ip_n, 0x03);
	buf[len++] = ' ';
	buf[len++] = 'm';
	buf[len++] = '\n';
	buf[len++] = 0;

	if (HPDF_Stream_WriteStr(attr->stream, buf) != HPDF_OK)
		return HPDF_CheckError(page->error);

	attr->cur_pos.x = x;
	attr->cur_pos.y = y;
	attr->str_pos = attr->cur_pos;
	attr->gmode = HPDF_GMODE_PATH_OBJECT;

	return ret;
}

// 画线路径 目标位置 并移动当前位置
HPDF_EXPORT(HPDF_STATUS)
hpdf_page_line_to(
	HPDF_Page page,
	HPDF_INT32 x,
	HPDF_INT32 y,
	HPDF_UINT8 ip_n)
{
	HPDF_STATUS ret = HPDF_Page_CheckState(page, HPDF_GMODE_PATH_OBJECT);
	char buf[HPDF_TMP_BUF_SIZ];
	char len;
	HPDF_PageAttr attr;

	HPDF_PTRACE((" HPDF_Page_LineTo\n"));

	if (ret != HPDF_OK)
		return ret;

	attr = (HPDF_PageAttr)page->attr;

	len = i32_to_string(buf, x, ip_n, 0x03);
	buf[len++] = ' ';
	len += i32_to_string(buf + len, y, ip_n, 0x03);
	buf[len++] = ' ';
	buf[len++] = 'l';
	buf[len++] = '\n';
	buf[len++] = 0;

	if (HPDF_Stream_WriteStr(attr->stream, buf) != HPDF_OK)
		return HPDF_CheckError(page->error);

	// attr->cur_pos.x = x;
	// attr->cur_pos.y = y;
	return ret;
}

// 设置路径当前位置坐标
HPDF_EXPORT(HPDF_STATUS)
hpdf_page_p1_move_to(
	HPDF_Page page,
	HPDF_INT32 x,
	HPDF_INT32 y)
{
	HPDF_STATUS ret = HPDF_Page_CheckState(page, HPDF_GMODE_PAGE_DESCRIPTION |
													 HPDF_GMODE_PATH_OBJECT);
	char buf[HPDF_TMP_BUF_SIZ];
	char len;
	HPDF_PageAttr attr;

	HPDF_PTRACE((" HPDF_Page_MoveTo\n"));

	if (ret != HPDF_OK)
		return ret;

	attr = (HPDF_PageAttr)page->attr;

	len = i32_to_string(buf, x, 0x51, 0x03);
	buf[len++] = ' ';
	len += i32_to_string(buf + len, y, 0x51, 0x03);
	buf[len++] = ' ';
	buf[len++] = 'm';
	buf[len++] = '\n';
	buf[len++] = 0;

	if (HPDF_Stream_WriteStr(attr->stream, buf) != HPDF_OK)
		return HPDF_CheckError(page->error);

	attr->cur_pos.x = x;
	attr->cur_pos.y = y;
	attr->str_pos = attr->cur_pos;
	attr->gmode = HPDF_GMODE_PATH_OBJECT;

	return ret;
}

// 画线路径 目标位置 并移动当前位置
HPDF_EXPORT(HPDF_STATUS)
hpdf_page_p1_line_to(
	HPDF_Page page,
	HPDF_INT32 x,
	HPDF_INT32 y)
{
	HPDF_STATUS ret = HPDF_Page_CheckState(page, HPDF_GMODE_PATH_OBJECT);
	char buf[HPDF_TMP_BUF_SIZ];
	char len;
	HPDF_PageAttr attr;

	HPDF_PTRACE((" HPDF_Page_LineTo\n"));

	if (ret != HPDF_OK)
		return ret;

	attr = (HPDF_PageAttr)page->attr;

	len = i32_to_string(buf, x, 0x51, 0x03);
	buf[len++] = ' ';
	len += i32_to_string(buf + len, y, 0x51, 0x03);
	buf[len++] = ' ';
	buf[len++] = 'l';
	buf[len++] = '\n';
	buf[len++] = 0;

	if (HPDF_Stream_WriteStr(attr->stream, buf) != HPDF_OK)
		return HPDF_CheckError(page->error);

	// attr->cur_pos.x = x;
	// attr->cur_pos.y = y;
	return ret;
}

/* re */
HPDF_EXPORT(HPDF_STATUS)
hpdf_page_rectangle(
	HPDF_Page page,
	HPDF_INT32 x,
	HPDF_INT32 y,
	HPDF_INT32 width,
	HPDF_INT32 height,
	HPDF_UINT8 ip_n)
{
	HPDF_STATUS ret = HPDF_Page_CheckState(page, HPDF_GMODE_PAGE_DESCRIPTION |
													 HPDF_GMODE_PATH_OBJECT);
	char pdf_buf[HPDF_TMP_BUF_SIZ];
	char length = 0;
	HPDF_PageAttr attr;

	HPDF_PTRACE((" HPDF_Page_Rectangle\n"));

	if (ret != HPDF_OK)
		return ret;

	attr = (HPDF_PageAttr)page->attr;

	length += i32_to_string(&pdf_buf[length], x, ip_n, 0x03);
	pdf_buf[length++] = ' ';
	length += i32_to_string(&pdf_buf[length], y, ip_n, 0x03);
	pdf_buf[length++] = ' ';
	length += i32_to_string(&pdf_buf[length], width, ip_n, 0x03);
	pdf_buf[length++] = ' ';
	length += i32_to_string(&pdf_buf[length], height, ip_n, 0x03);
	pdf_buf[length++] = ' ';
	length += copy_str("re\n", &pdf_buf[length], 6);

	if (HPDF_Stream_WriteStr(attr->stream, pdf_buf) != HPDF_OK)
		return HPDF_CheckError(page->error);

	// attr->cur_pos.x = x;
	// attr->cur_pos.y = y;
	attr->str_pos = attr->cur_pos;
	attr->gmode = HPDF_GMODE_PATH_OBJECT;

	return ret;
}

// 划曲线路径到目标位置 - 三次贝尔曲线 - 并移动当前位置到x3,y3
HPDF_EXPORT(HPDF_STATUS)
hpdf_page_curve123_to(
	HPDF_Page page,
	HPDF_INT32 x1,
	HPDF_INT32 y1,
	HPDF_INT32 x2,
	HPDF_INT32 y2,
	HPDF_INT32 x3,
	HPDF_INT32 y3,
	HPDF_UINT8 ip_n)
{
	HPDF_STATUS ret = HPDF_Page_CheckState(page, HPDF_GMODE_PATH_OBJECT);
	char pdf_buf[HPDF_TMP_BUF_SIZ];
	char length = 0;
	HPDF_PageAttr attr;

	HPDF_PTRACE((" HPDF_Page_CurveTo\n"));

	if (ret != HPDF_OK)
		return ret;

	attr = (HPDF_PageAttr)page->attr;

	length += i32_to_string(&pdf_buf[length], x1, ip_n, 0x03);
	pdf_buf[length++] = ' ';
	length += i32_to_string(&pdf_buf[length], y1, ip_n, 0x03);
	pdf_buf[length++] = ' ';
	length += i32_to_string(&pdf_buf[length], x2, ip_n, 0x03);
	pdf_buf[length++] = ' ';
	length += i32_to_string(&pdf_buf[length], y2, ip_n, 0x03);
	pdf_buf[length++] = ' ';
	length += i32_to_string(&pdf_buf[length], x3, ip_n, 0x03);
	pdf_buf[length++] = ' ';
	length += i32_to_string(&pdf_buf[length], y3, ip_n, 0x03);
	pdf_buf[length++] = ' ';
	length += copy_str("c\n", &pdf_buf[length], 6);

	if (HPDF_Stream_WriteStr(attr->stream, pdf_buf) != HPDF_OK)
		return HPDF_CheckError(page->error);

	// attr->cur_pos.x = x3;
	// attr->cur_pos.y = y3;

	return ret;
}

/* v */
HPDF_EXPORT(HPDF_STATUS)
hpdf_page_curve23_to(
	HPDF_Page page,
	HPDF_INT32 x2,
	HPDF_INT32 y2,
	HPDF_INT32 x3,
	HPDF_INT32 y3,
	HPDF_UINT8 ip_n)
{
	HPDF_STATUS ret = HPDF_Page_CheckState(page, HPDF_GMODE_PATH_OBJECT);
	char pdf_buf[HPDF_TMP_BUF_SIZ];
	char length = 0;
	HPDF_PageAttr attr;

	HPDF_PTRACE((" HPDF_Page_CurveTo2\n"));

	if (ret != HPDF_OK)
		return ret;

	attr = (HPDF_PageAttr)page->attr;

	length += i32_to_string(&pdf_buf[length], x2, ip_n, 0x03);
	pdf_buf[length++] = ' ';
	length += i32_to_string(&pdf_buf[length], y2, ip_n, 0x03);
	pdf_buf[length++] = ' ';
	length += i32_to_string(&pdf_buf[length], x3, ip_n, 0x03);
	pdf_buf[length++] = ' ';
	length += i32_to_string(&pdf_buf[length], y3, ip_n, 0x03);
	pdf_buf[length++] = ' ';
	length += copy_str("v\n", &pdf_buf[length], 6);

	if (HPDF_Stream_WriteStr(attr->stream, pdf_buf) != HPDF_OK)
		return HPDF_CheckError(page->error);

	// attr->cur_pos.x = x3;
	// attr->cur_pos.y = y3;

	return ret;
}

/* y */
HPDF_EXPORT(HPDF_STATUS)
hpdf_page_curve13_to(
	HPDF_Page page,
	HPDF_INT32 x1,
	HPDF_INT32 y1,
	HPDF_INT32 x3,
	HPDF_INT32 y3,
	HPDF_UINT8 ip_n)
{
	HPDF_STATUS ret = HPDF_Page_CheckState(page, HPDF_GMODE_PATH_OBJECT);
	char pdf_buf[HPDF_TMP_BUF_SIZ];
	char length = 0;
	HPDF_PageAttr attr;

	HPDF_PTRACE((" HPDF_Page_CurveTo3\n"));

	if (ret != HPDF_OK)
		return ret;

	attr = (HPDF_PageAttr)page->attr;

	length += i32_to_string(&pdf_buf[length], x1, ip_n, 0x03);
	pdf_buf[length++] = ' ';
	length += i32_to_string(&pdf_buf[length], y1, ip_n, 0x03);
	pdf_buf[length++] = ' ';
	length += i32_to_string(&pdf_buf[length], x3, ip_n, 0x03);
	pdf_buf[length++] = ' ';
	length += i32_to_string(&pdf_buf[length], y3, ip_n, 0x03);
	pdf_buf[length++] = ' ';
	length += copy_str("y\n", &pdf_buf[length], 6);

	if (HPDF_Stream_WriteStr(attr->stream, pdf_buf) != HPDF_OK)
		return HPDF_CheckError(page->error);

	// attr->cur_pos.x = x3;
	// attr->cur_pos.y = y3;

	return ret;
}

// 画圆路径
// 圆形三次贝尔曲线系数 0.552284749831
// q15数 = 18097
HPDF_EXPORT(HPDF_STATUS)
hpdf_page_cycle(
	HPDF_Page page,
	ii32 x,
	ii32 y,
	ii32 c,
	uu8 ip_n)
{
	ii32 x1, y1, x2, y2, x3, y3, bl;
	HPDF_STATUS ret;

	// 起点
	hpdf_page_move_to(page, x - c, y, ip_n);

	// 贝尔曲线系数
	bl = c * 18097 >> 15;

	// 曲线参数
	x1 = x - c;
	y1 = y + bl;
	x2 = x - bl;
	y2 = y + c;
	x3 = x;
	y3 = y + c;
	ret = hpdf_page_curve123_to(page, x1, y1, x2, y2, x3, y3, ip_n);

	x1 = x + bl;
	y1 = y + c;
	x2 = x + c;
	y2 = y + bl;
	x3 = x + c;
	y3 = y;
	ret = hpdf_page_curve123_to(page, x1, y1, x2, y2, x3, y3, ip_n);

	x1 = x + c;
	y1 = y - bl;
	x2 = x + bl;
	y2 = y - c;
	x3 = x;
	y3 = y - c;
	ret = hpdf_page_curve123_to(page, x1, y1, x2, y2, x3, y3, ip_n);

	x1 = x - bl;
	y1 = y - c;
	x2 = x - c;
	y2 = y - bl;
	x3 = x - c;
	y3 = y;
	ret = hpdf_page_curve123_to(page, x1, y1, x2, y2, x3, y3, ip_n);

	return ret;
}
